home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / rexx / cdmp.lha / cdmp.rx < prev   
Encoding:
Text File  |  2000-09-14  |  24.6 KB  |  884 lines

  1. /**********************************************************************************************************************
  2.  
  3. $VER: cdmp.rx v1.1 (26.08.2000)
  4.  
  5. Erstellt: J.Klingele 03.2000
  6. Email:    jklingele@gmx.de
  7.  
  8. liest tracks (titel) von cd und wandelt diese ins mp3 format
  9.  
  10. benötigt cdda zum einlesen der CD
  11.      und lame zum erzeugen der mp3 files
  12. Beide im Suchpfad (vorzugsweise c:)
  13.  
  14. V1.0 10.08.2000 - 1. vollständige, inoffizielle Version - jk
  15. V1.1 26.08.2000 - Unterstützung von CDID's, bessere Fehlerbehandlung und Kontrolle, Parameter für mp3-extension
  16.                   1. Aminet Release  - jk
  17.  
  18.  
  19. ***********************************************************************************************************************/
  20.  
  21.  
  22. /******* Globale Parameter Variablen *******/
  23.  
  24. titelpfad    = "CD-A:"            /* Pfad zum speichern der tracks und sonstiger datenfiles, MUSS mit : oder / enden  */
  25. mp3pfad      = "MP3:"             /* Pfad zum speichern der mp3-files, MUSS mit : oder / enden                        */
  26. cdid_dir     = "CDID:"            /* Pfad zu den CDID's                                                               */
  27.  
  28. titellist    = "titelliste"       /* Dateiname zum abspeichern der eingegeben Titel, wird für Restore benutzt         */
  29. cdlist       = "ram:cdliste"      /* Dateiname der Titelliste von cdda, wird nut temporär zum einlesen verw.          */
  30. mp_ext       = ".mp3"             /* extension für mp3-Dateien                                                        */
  31.  
  32. plan         = "e"                /* cdda-Modus e=atapi                                                               */
  33. lameopt      = "-b 160"           /* optionstring für lame                                                            */
  34.  
  35. debug        = 0                  /* Debugmode und -anzeige 0=nein 1=ja                                               */
  36. del_titel    = 0                  /* CD-Titel nach konvertierung löschen 0=nein 1=ja                                  */
  37. bpb          = 2352               /* Bytes per Block ca. Wert                                                         */
  38. skip_lo      = 175                /* Anzahl der Blocks die vom Leadout abgezogen werden. 1s ca. 75 Blocks (2,3s)      */
  39. repl_spc     = 1                  /* Bei Eingabe der CD-Titelnamen Leerzeichen durch '_' ersetzen 0=nein 1=ja         */
  40.  
  41. max_name_len = 30                 /* max. Dateinamenlänge ffs=30 Zeichen                                              */
  42. dirty_char   = '~%#?<>|()[]":`;*' /* ungültige Zeichen die bei der Namenseingabe ersetzt werden müssen.               */
  43.  
  44.  
  45. /*******************************************
  46.  
  47. Sonstige Globale Variablen
  48.  
  49. {  cd.                       - Stammvariable mit den Daten der einzelnen Titel auf CD
  50.    cd.titel.                 - Daten eines titels
  51.    cd.titel.nr               - Titelnummer
  52.            .name             - Titelname
  53.            .ip               - Interpret
  54.            .cdn              - Dateiname (ohne Pfad) zum abspeichern auf HD
  55.            .start            - Startblock
  56.            .ende             - Endblock
  57.            .laenge           - Laenge in Blocks
  58.            .zeit             - Spielzeit
  59. }
  60.  
  61. {  rip.                      - Stammvariable mit Daten der abzuspeichernden und umzuwandelnden Titel
  62.    rip.titel.                - Daten eines titels
  63.    rip.titel.cdt             - (CD) Titelnummer (dient als Verweis auf cd.titel.nr)
  64.             .mpn             - mp3 Dateiname zum abspeichern
  65.             .cut_lo          - zusätzlicher Abzug vom lead-out (optional per eingabe)
  66. }
  67.  
  68. anz_titel                    - Anzahl der Titel auf CD
  69. anz_save                     - Anzahl der Titel die eingelesen werden sollen
  70. mp3                          - mit mp3 Konvertierung j/n
  71. restore                      - restorefunktion, alte Daten verwenden j/n
  72. listname                     - übergebener dateiname bei Programmaufruf, sollte bestehende Titelliste enthalten
  73. list_in                      - dateiname zum einlesen einer titelliste (wird entw. auf titellist oder listname gesetzt)
  74. cdid                         - ID String der CD im Laufwerk
  75. cdid_rest                    - ID String der zu bearbeitenden CD bei restore
  76.  
  77.  
  78. Lokale Variablen
  79.  
  80.  a, b, c, akt_t, datei_in, datei_out, cdnr, zeile, gr, cut, temp, dummy
  81.  
  82. 'Lokale' Variablen in Unterprogrammen
  83.  
  84.  sdatei, sstart, sende, sa, s_name, s_len
  85.  
  86. *********************************************/
  87.  
  88. SIGNAL ON break_c  /* abbruch bei CTRL-C */
  89.  
  90. anz_titel = -1
  91. anz_save  = -1
  92. mp3       = "N"
  93.  
  94. IF EXISTS(cdid_dir) THEN
  95.   cdid_mode = 1
  96. ELSE
  97.   cdid_mode = 0
  98.  
  99. /** 1. Programmstart mit restore einer gespeicherten Sitzung ? **/
  100.  
  101. /* Dateiname zu bestehender Titelliste übergeben ? */
  102. PARSE ARG listname
  103.  
  104. IF listname ~== "" THEN
  105.   list_in = titelpfad||listname
  106.  
  107. ELSE
  108.   list_in = titelpfad||titellist /* ohne Übergabeparameter wird der Standardname fürs Backup verwendet */
  109.  
  110. IF debug == 1 THEN SAY "<"listname">"
  111.  
  112. /** 1a. Prüfen ob Bearbeitung zuvor unterbrochen wurde **/
  113.  
  114. IF EXISTS(list_in) THEN DO
  115.  
  116.   /* alte Werte wieder einlesen */
  117.   OPEN(datei_in,list_in,R)
  118.  
  119.   a = 0
  120.   rip. = ""
  121.  
  122.   cdid_rest = READLN(datei_in)
  123.   mp3       = READLN(datei_in)
  124.  
  125.   DO WHILE ~eof(datei_in)
  126.  
  127.     a = a +1
  128.  
  129.     rip.a.cdt    = READLN(datei_in)
  130.     rip.a.mpn    = READLN(datei_in)
  131.     rip.a.cut_lo = READLN(datei_in)
  132.  
  133.     IF debug == 1 THEN
  134.       SAY "ID: "cdid_rest" - MP3: "mp3" - Titel "a": "rip.a.cdt" - Dateiname : "rip.a.mpn" Abzug : "rip.a.cut_lo
  135.  
  136.   END /* do while */
  137.  
  138.   CLOSE(datei_in)
  139.  
  140.   a = a -1 /* Da das Dateiende hinter der letzen Zeile ist gibts immer einen leeren Satz */
  141.  
  142.   /* Daten vorhanden ?? (>>>>>> evt. mal durch irgendeine Checksumme ersetzen) */
  143.   IF (rip.a.cdt ~== "") & (RIGHT(rip.a.mpn,4) == mp_ext) THEN DO
  144.  
  145.     /* Variablen für nachfolgende Routinen setzen */
  146.     anz_save = a
  147.  
  148.     SAY
  149.     IF mp3 == "J" THEN DO
  150.  
  151.       SAY "> Alte Angaben eingelesen, folgende MP3-files sollen erzeugt werden:"
  152.       SAY
  153.       SAY " CD-Titel | MP3-Name                       | kürzen um"
  154.       SAY "-------------------------------------------------------"
  155.  
  156.       DO a = 1 to anz_save
  157.  
  158.         SAY INSERT('','',0,6-(rip.a.cdt > 9),' ')||rip.a.cdt"   - "rip.a.mpn||INSERT(' ','',1,max_name_len - LENGTH(rip.a.mpn),' ')"- " (skip_lo + rip.a.cut_lo) % 75"s."
  159.  
  160.       END /* Do */
  161.  
  162.     END /* if mp3 */
  163.  
  164.     ELSE DO  /* vorerst keine CDID Auswertung, wird eh selten gebraucht */
  165.  
  166.       SAY "> Alte Angaben eingelesen, folgende CD-files sollen erzeugt werden:"
  167.       SAY
  168.       SAY " CD-Titel"
  169.       SAY "----------"
  170.  
  171.       DO a = 1 to anz_save
  172.  
  173.         SAY INSERT('','',0,5-(rip.a.cdt > 9))||rip.a.cdt
  174.  
  175.       END /* Do */
  176.  
  177.     END /* else - if mp3 */
  178.  
  179.     SAY
  180.  
  181.     /* Wenn ja, ermitteln ob die alte Sitzung fortgesetzt werden soll */
  182.  
  183.     IF list_in == titelpfad||titellist THEN
  184.       SAY "> Soll die abgebrochene Bearbeitung der letzten CD mit diesen Daten weitergeführt werden (j/N)?"
  185.  
  186.     ELSE
  187.       SAY "> Soll die Bearbeitung mit diesen Daten von <"listname"> begonnen werden (j/N)?"
  188.  
  189.     PULL restore
  190.  
  191.     IF restore == "J" THEN DO
  192.  
  193.        /* CD-Liste wird auf alle Fälle wieder neu eingelesen, sicher ist sicher */
  194.        CALL get_toc()
  195.  
  196.        DO WHILE cdid ~== cdid_rest /* warten bis richtige CD eingelegt wurde */
  197.  
  198.           SAY
  199.           SAY "> ACHTUNG !! Falsche CD, unbedingt wieder die passende CD einlegen"
  200.           SAY "  und mit Return bestätigen."
  201.  
  202.           PULL temp  /* auf Return warten */
  203.  
  204.           CALL get_toc()
  205.  
  206.        END /* do while */
  207.  
  208.     END /* if restore */
  209.  
  210.     ELSE DO
  211.  
  212.       restore = "N" /* restore und anz_save auf definierten Wert setzen sonst gibts evt. Probleme */
  213.       anz_save = 0
  214.  
  215.     END
  216.  
  217.   END /* if rip.. */
  218.  
  219.   ELSE DO /* Notbremse bei Fehler */
  220.  
  221.     SAY "> Daten der letzen Bearbeitung konnten nicht eingelesen werden."
  222.     SAY "> Wahrscheinlich ist die Datei "list_in" defekt. :-("
  223.     SAY "> Hilft nichts, alles nochmal neu eingeben ;-)"
  224.  
  225.     restore = "N"
  226.     anz_save = 0
  227.     mp3 = "N"
  228.  
  229.   END /* else - if rip.. */
  230.  
  231. END /* if exists */
  232.  
  233.  
  234. /** 1b. Inhaltsverzeichnis einlesen und auswerten **/
  235.  
  236. IF (restore ~== "J") THEN DO  /* aber nicht wenn eine Sitzung fortgeführt wird */
  237.  
  238.   CALL get_toc()
  239.  
  240.   IF (anz_titel > 0) THEN DO
  241.  
  242.     SAY
  243.     SAY "> CD Inhalt eingelesen, insgesamt "anz_titel" Titel:"
  244.     SAY
  245.  
  246.     IF cdid_mode == 1 THEN DO
  247.  
  248.       li = 10  /* mindestlaenge interpret (wegen text) */
  249.       ln = 6   /* mindestlaenge titel */
  250.  
  251.       DO a = 1 to anz_titel
  252.  
  253.         IF LENGTH(cd.a.ip) > li THEN li = LENGTH(cd.a.ip)+1      /* min.laenge interpret anpassen wenn länger */
  254.         IF LENGTH(cd.a.name) > ln THEN ln = LENGTH(cd.a.name)+1  /* min.laenge titel anpassen wenn länger */
  255.  
  256.       END /* do a */
  257.  
  258.       SAY "CD-Interpret: "cd.0.ip
  259.       SAY "CD-Titel    : "cd.0.name
  260.       SAY
  261.  
  262.       b= " Titel | Interpret"INSERT('','',0,li-9,' ')"| Titel"INSERT('','',0,ln-5,' ')"| Länge "  /* Länge des Headers */
  263.  
  264.       SAY b
  265.       SAY INSERT('','',1,LENGTH(b)+2,'-')
  266.  
  267.       DO a = 1 to anz_titel /* titel ausgeben */
  268.  
  269.         SAY INSERT('','',0,4-(a > 9),' ')||cd.a.nr"  - "cd.a.ip||INSERT('','',0,li-LENGTH(cd.a.ip),' ')"- "cd.a.name||INSERT('','',0,ln-LENGTH(cd.a.name),' ')"- "cd.a.zeit
  270.  
  271.       END /* do a */
  272.  
  273.       SAY INSERT('','',0,LENGTH(b)+3,'-')
  274.       SAY INSERT('','',0,li+ln+5,' ')"Gesamt: "cd.a.zeit
  275.       SAY
  276.  
  277.     END /* if cdid_mode */
  278.  
  279.     ELSE DO  /* keine cdid vorhanden, daher auch keine titelnamen */
  280.  
  281.       SAY
  282.       SAY "> CD Inhalt eingelesen, insgesamt "anz_titel" Titel:"
  283.       SAY
  284.       SAY " Titel | Länge"
  285.       SAY "--------------------"
  286.  
  287.       DO a = 1 to anz_titel
  288.  
  289.         SAY INSERT('','',0,5-(a > 9),' ')||cd.a.nr" - "cd.a.zeit
  290.  
  291.       END /* Do */
  292.  
  293.       SAY "--------------------"
  294.       SAY " Gesamt: "cd.a.zeit
  295.       SAY
  296.  
  297.     END
  298.  
  299.   /** 2. Titel zum abspeichern auswaehlen **/
  300.  
  301.     akt_t = 0
  302.     rip.0.cdt = "dummy"
  303.     gr = 0
  304.  
  305.     /* titel zum Abspeichern holen bis keine Eingabe mehr */
  306.     DO UNTIL rip.akt_t.cdt==""
  307.  
  308.       akt_t = akt_t +1
  309.  
  310.       SAY "> Bitte "akt_t". gewünschten Titel eingeben (1-"anz_titel", b = letzten Titel löschen, nur Return = ende): "
  311.       PULL rip.akt_t.cdt
  312.  
  313.       /* evt. eingegebener Abzug vom Leadout auswerten */
  314.       IF LEFT(rip.akt_t.cdt,1) == "-" THEN DO
  315.  
  316.          /* leadout abzug vom Titel trennen */
  317.          PARSE VALUE rip.akt_t.cdt WITH cut' 'temp
  318.  
  319.          IF temp == "" THEN  /* Titel vergessen oder falsch eingegeben */
  320.  
  321.             rip.akt_t.cdt = "X"
  322.  
  323.          ELSE DO
  324.  
  325.            rip.akt_t.cdt = temp  /* titel wieder eintragen */
  326.  
  327.            cut = TRANSLATE(cut,'.',',') /* komma durch punkt ersetzten wenn vorhanden */
  328.  
  329.            /* und neuen zusätzlichen abzug ausrechnen. Scheint insgesamt etwas kompliziert, aber so kann ich mehr oder
  330.               weniger als den standardabzug abschneiden */
  331.            rip.akt_t.cut_lo = ((cut * -75) % 1) - skip_lo
  332.  
  333.            /* abzug + standardabzug dürfen natürlich nicht länger als der titel sein */
  334.            IF (rip.akt_t.cut_lo + skip_lo) > cd.temp.laenge THEN DO
  335.  
  336.              SAY "> Scherzkeks, das machen wir nochmal..."
  337.  
  338.              rip.akt_t.cut_lo = 0
  339.              rip.akt_t.cdt    = "X"
  340.  
  341.            END /* if */
  342.  
  343.            IF debug == 1 THEN
  344.              SAY "Abzug: "cut" Titel: "temp" zus.Abzug: "rip.akt_t.cut_lo" Standardabz.: "skip_lo
  345.  
  346.         END /* if temp */
  347.  
  348.       END /* if left */
  349.  
  350.       ELSE
  351.         rip.akt_t.cut_lo = 0 /* ohne Eingabe standardabzug nicht ändern */
  352.  
  353.       /* Eingabe erfolgt oder -> eingabeende ? */
  354.       IF rip.akt_t.cdt ~== "" THEN DO
  355.  
  356.         /* erstmal schauen ob wir den Titel nicht schon hatten. Geht auch eleganter aber es sind */
  357.         /* ja höchstens 20 Titel                                                                 */
  358.  
  359.         DO a = 1 TO (akt_t -1)
  360.  
  361.            IF rip.akt_t.cdt == rip.a.cdt THEN DO
  362.  
  363.              SAY ">>>> Also den Titel hatten wir schon mal."
  364.              SAY
  365.  
  366.              rip.akt_t.cdt = "X" /* X ist eine ungültige Angabe und wird im Select entsprechend behandelt */
  367.  
  368.            END /* if rip.. */
  369.  
  370.         END /* do a */
  371.  
  372.         SELECT
  373.  
  374.           /* Titel im erlaubten Bereich ? */
  375.           WHEN (rip.akt_t.cdt >= 1) & (rip.akt_t.cdt <= anz_titel) THEN DO
  376.  
  377.             a = rip.akt_t.cdt
  378.  
  379.             IF cdid_mode == 1 THEN                        /* zugehörenden mp3-namen generieren */
  380.  
  381.               IF LENGTH(cd.a.cdn) > max_name_len-4 THEN   /* genug Platz für extension ? */
  382.                 rip.akt_t.mpn = LEFT(cd.a.cdn, max_name_len-4)||".mp3"
  383.               ELSE
  384.                 rip.akt_t.mpn = cd.a.cdn||".mp3"
  385.  
  386.             ELSE /* if cdid_mode */
  387.               rip.akt_t.mpn = "Titel"rip.akt_t.cdt".mp3"  /* zugehörenden default mp3-namen generieren */
  388.  
  389.             /* Vorabinfo wieviel Platz ca. benötigt wird */
  390.             gr = gr + (((cd.a.laenge - rip.akt_t.cut_lo) * bpb) % 1048576)
  391.  
  392.             SAY "> benötigter Speicherplatz bis jetzt ca. "gr" MB."
  393.             SAY
  394.  
  395.           END /* when */
  396.  
  397.           /* letzte Eingabe löschen */
  398.           WHEN (rip.akt_t.cdt == "B") & (akt_t > 1) THEN DO
  399.  
  400.             akt_t = akt_t -2  /* laufvariable zurücksetzen */
  401.  
  402.             /* Speicheranzeige korrigieren und neu ausgeben, gibt natürlich Rundungsfehler ist aber eh' nur ca. */
  403.             a = rip.akt_t.cdt
  404.             gr = gr - (((cd.a.laenge - rip.akt_t.cut_lo) * bpb) % 1048576) + 1
  405.  
  406.             SAY "> benötigter Speicherplatz neu jetzt ca. "gr" MB."
  407.             SAY
  408.  
  409.           END /* when */
  410.  
  411.           /* falsche Eingabe */
  412.           OTHERWISE
  413.  
  414.             akt_t = akt_t -1  /* laufvariable wieder zurücksetzen */
  415.  
  416.         END /* Select */
  417.  
  418.       END /* if rip.. */
  419.  
  420.     END /* Do until */
  421.  
  422.  
  423.     anz_save = akt_t -1
  424.  
  425.     /* Titel ausgewählt? */
  426.     IF anz_save > 0 THEN DO
  427.  
  428.       /* ermitteln ob auch mp3 erzeugt werden soll */
  429.       SAY "> Sollen die Songs auch gleich ins mp3-Format umgewandelt werden? (j/N) "
  430.  
  431.       PULL mp3
  432.  
  433.       IF mp3 == "J" THEN DO
  434.  
  435.         IF cdid_mode == 0 THEN DO
  436.  
  437.           /* filenamen für mp3-files ermitteln. Bei vorhandenen cdids wUrden die Namen automatisch generiert.
  438.              Prinzipiell können auch noch Pfadangaben vor dem Filenamen erfolgen solange die max. Länge von
  439.              26 Zeichen nicht überschritten wird (dir/dir/name).
  440.              Einfacher ist es aber den globalen Pfad richtig einzustellen.
  441.  
  442.              Überprüfung der Gültigkeit:
  443.              FFS max 30 Zeichen (26 + .mp3 = 30)
  444.              keine ~ % # ? < > | ( ) [ ] " Zeichen
  445.           */
  446.  
  447.           a = 0
  448.           b = ""
  449.  
  450.           /* Die Eingabe der Dateinnamen kann nicht mit Pull erfolgen da dabei alles in Grossbuchstaben
  451.              umgewandelt wird. Der einzige mir bekannte Weg dies ohne CON: zu umgehen, ist das Einlesen mit Parse
  452.              aus STDERR. Kollidiert allerdings mit evt. offenen Debug-Fenstern
  453.           */
  454.           CALL OPEN(STDERR, "*", 'R')
  455.  
  456.           DO UNTIL a == anz_save
  457.  
  458.             a = a +1
  459.  
  460.             SAY
  461.             SAY "> Dateiname für mp3-file von Titel "rip.a.cdt" eingeben (ohne extension, default = "rip.a.mpn") : "
  462.  
  463.             PARSE EXTERNAL b
  464.  
  465.             /* wenn ein Name eingegeben wurde diesen uebernehmen ansonsten den defaultnamen verwenden */
  466.             IF b ~== "" THEN DO
  467.  
  468.               temp = b
  469.  
  470.               b = create_name(b, max_name_len - LENGTH(mp_ext))
  471.  
  472.               IF b ~== temp THEN DO
  473.                 SAY
  474.                 SAY "> Dateiname angepasst:" b
  475.  
  476.               END /* if b/temp */
  477.  
  478.               rip.a.mpn = b||mp_ext
  479.  
  480.             END /* if b/"" */
  481.  
  482.           END /* Do until */
  483.  
  484.           CLOSE(STDERR) /* wir sind ein ordentliches Völkchen ;-) */
  485.  
  486.         END /* if cdid_mode */
  487.  
  488.       END /* if mp3 */
  489.  
  490.     END /* if anz_save */
  491.  
  492.   END /* if anz_titel */
  493.  
  494. END /* if restore */
  495.  
  496. /** jetzt kommt sie eigentliche Arbeit, natürlich nur wenn auch Titel ausgewählt wurden **/
  497.  
  498. IF anz_save > 0 THEN DO
  499.  
  500.   /* bei restore wird gleich begonnen, ansonsten erfolgt abfrage ob die angaben nur gespeichert werden sollen.
  501.      Damit kann während eine CD bearbeitet wird bereits die nächste vorbereiten. Skript dann mit Dateinamen starten. */
  502.  
  503.   IF restore ~== "J" THEN DO
  504.     SAY "> Gleich mit der Bearbeitung beginnen oder Angaben zur späteren Abarbeitung speichern (g/S)?"
  505.  
  506.     PULL doit
  507.  
  508.   END /* if restore */
  509.  
  510.   ELSE
  511.     doit = "G"
  512.  
  513.   IF doit == "G" THEN DO
  514.  
  515.     /* erstmal bisherige Angaben speichern. Abspeichern erfolgt erst jetzt da es bei späterer bearbeitung nicht
  516.        nötig ist die Daten unter dem Backupnamen zu speichern, evt. würde das auch mit einer gerade laufenden
  517.        Sitzung kollidieren. Tut es zwar auch wenn eine Instanz gerade mp3 erzeugt und die neue nur cd-files, aber
  518.        einen Tod muss man sterben. Wenn ich erst nach dem Erzeugen der CD-files abspeichere ist das Risiko zu gross
  519.        dass die Daten durch Absturz verlorengehen. (die ca. 50 MB einer Datei quälen sich bei mir in ca. 40s.
  520.        auf die Platte.)
  521.     */
  522.     CALL save_datei(titellist,1,anz_save) /* Titelliste für restore abspeichern */
  523.  
  524.     a=1
  525.  
  526.     SAY
  527.  
  528.     /* alle Titel erstmal auf HD speichern. Keine Abfrage auf ausreichend freien Speicherplatz. Wüsste nicht wie */
  529.     DO WHILE a <= anz_save
  530.  
  531.       akt_t = rip.a.cdt
  532.  
  533.       cd.akt_t.laenge = cd.akt_t.laenge - rip.a.cut_lo /* titellaenge um evt. eingegebenen abzug korrigieren */
  534.  
  535.       gr = (cd.akt_t.laenge * bpb) % 1048576   /* nur ca-Wert */
  536.  
  537.       SAY "> Speichere Lied Nr." akt_t" als "titelpfad||cd.akt_t.cdn", Grösse ca. "gr" MB"
  538.  
  539.       /* CD-Titel einlesen und abspeichern */
  540.       IF debug == 1 THEN
  541.         SAY "cdda PLAN="plan" MUTE FILE="'"'titelpfad||cd.akt_t.cdn'"'" START="cd.akt_t.start" LENGTH="cd.akt_t.laenge
  542.       
  543.       ELSE
  544.         ADDRESS COMMAND "cdda PLAN="plan" MUTE FILE="'"'titelpfad||cd.akt_t.cdn'"'" START="cd.akt_t.start" LENGTH="cd.akt_t.laenge
  545.  
  546.       a = a +1
  547.  
  548.     END /* Do while */
  549.  
  550.     SAY
  551.     SAY "> CD wird nicht mehr benötigt"
  552.  
  553.     /* ggf. mp3-files erzeugen */
  554.     IF mp3 == "J" THEN DO
  555.  
  556.       SAY
  557.       SAY "> erzeuge jetzt die entsprechenden mp3-files ->"
  558.  
  559.       a = 1
  560.  
  561.       DO WHILE a <= anz_save
  562.  
  563.         b = rip.a.cdt
  564.  
  565.         SAY
  566.         SAY "> Titel Nr." b "unter "mp3pfad||rip.a.mpn
  567.         SAY
  568.  
  569.         /* mp3 erzeugen */
  570.         IF debug == 1 THEN
  571.           SAY "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"'
  572.  
  573.         ELSE
  574.           ADDRESS COMMAND "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"'
  575.  
  576.         CALL save_datei(titellist,a+1,anz_save) /* fertige files aus abgespeicherter Titelliste entfernen */
  577.  
  578.         /* CD-file löschen */
  579.         IF debug == 1 THEN
  580.           SAY "Delete" '"'titelpfad||cd.b.cdn'"'
  581.  
  582.         IF (debug == 0) & (del_titel == 1) THEN
  583.           ADDRESS COMMAND "Delete >NIL: "'"'titelpfad||cd.b.cdn'"'
  584.  
  585.         a = a +1
  586.  
  587.       END /* Do while */
  588.  
  589.     END /* If mp3 */
  590.  
  591.   END /* if doit */
  592.  
  593.   ELSE DO  /* if doit */
  594.  
  595.     /* wenn die CD nicht direkt bearbeitet werden soll, brauche ich einen Dateinamen zum abspeichern der
  596.        Daten. Dies kann nicht der normale titellist sein da der jedesmal überschrieben wird. */
  597.     SAY "> Bitte Dateinamen zum Abspeichern der Titelliste eingeben. Am einfachsten sind"
  598.     SAY "> CD-Titel oder Interpret:"
  599.  
  600.     PULL listname
  601.  
  602.     listname = create_name(listname, max_name_len)
  603.  
  604.     SAY "> Danke, Titelliste wird unter <"listname"> gespeichert. Sobald die Liste bearbeitet werden soll,"
  605.     SAY "> cdmp.rx mit diesem Namen als Parameter starten. Also: cdmp.rx "listname
  606.  
  607.     CALL save_datei(listname,1,anz_save)
  608.  
  609.   END /* Else - if doit */
  610.  
  611. END /* If anz_save */
  612.  
  613. SAY
  614. SAY "> Ok, das war's und tschüssss........"
  615. SAY
  616.  
  617. ende:
  618.  
  619. EXIT
  620.  
  621.  
  622.  
  623. /**********************/
  624. /**** Sub-routinen ****/
  625. /**********************/
  626.  
  627. /****
  628.  
  629.   save_datei - speichert unter dem angebenen Dateinamen die Variablen cdid, mp3  und den Inhalt der rip-Variablen
  630.                von 'start' bis 'ende' im zugewiesenen Datenverzeichnis.
  631.                Keine Fehlerabfrage - zuviel Aufwand für relativ unwichtige Daten
  632.  
  633.   template: save_datei(datei,start,ende)
  634.  
  635. ****/
  636.  
  637. save_datei:
  638.  
  639.   PARSE ARG sdatei, sstart, sende
  640.  
  641.   IF sstart > sende THEN ADDRESS COMMAND "Delete >NIL: "titelpfad||sdatei
  642.  
  643.   ELSE DO
  644.  
  645.     OPEN(datei_out,titelpfad||sdatei,W)
  646.  
  647.     WRITELN(datei_out, cdid)
  648.     WRITELN(datei_out, mp3)
  649.  
  650.     DO sa = sstart TO sende
  651.  
  652.       IF debug == 1 THEN SAY "Speichere "rip.sa.cdt", "rip.sa.mpn", "rip.sa.cut_lo
  653.  
  654.       WRITELN(datei_out, rip.sa.cdt)
  655.       WRITELN(datei_out, rip.sa.mpn)
  656.       WRITELN(datei_out, rip.sa.cut_lo)
  657.  
  658.     END /* do sa */
  659.  
  660.     CLOSE(datei_out)
  661.  
  662.   END /* else */
  663.  
  664. RETURN
  665.  
  666. /* ---------------------------- */
  667.  
  668.  
  669. /****
  670.  
  671.   create_id  - erzeugt einen CDID String.
  672.  
  673.   globalen Variablen: anz_titel und cd.
  674.   lokale VAriablen  : sa
  675.  
  676. ****/
  677.  
  678. create_id:
  679.  
  680.   sa = "ID"
  681.  
  682.   IF anz_titel > 9 THEN
  683.  
  684.     sa = sa||anz_titel
  685.  
  686.   ELSE
  687.     sa = sa||'0'||anz_titel
  688.  
  689.   IF anz_titel == 2 THEN  /* kann man Singles mit 'nem CD-Rom lesen ? na, sicher ist sicher */
  690.     sa = sa||D2X(cd.anz_titel.ende+1,6)||D2X(cd.anz_titel.ende+1,6)
  691.  
  692.   ELSE
  693.     sa = sa||D2X(cd.3.start,6)||D2X(cd.anz_titel.ende+1,6)
  694.  
  695.   IF debug == 1 THEN SAY sa
  696.  
  697. RETURN sa
  698.  
  699. /* ---------------------------- */
  700.  
  701.  
  702. /****
  703.  
  704.   get_toc  - liest und überträgt das Inhaltsverzeichnis der CD.
  705.  
  706.   globale Variablen: cd., akt_titel, cdlist, anz_titel, cdid, cdid_mode
  707.   lokale Variablen : datei_in, zeile, akt_t, cdnr, dummy
  708.  
  709. ****/
  710.  
  711. get_toc:
  712.  
  713.   ADDRESS COMMAND "cdda plan=e list >"cdlist
  714.  
  715.   IF EXISTS(cdlist) THEN DO
  716.  
  717.     OPEN(datei_in,cdlist,R)
  718.  
  719.     /* 1.Zeile -> wegschmeissen) */
  720.     zeile = READLN(datei_in)
  721.  
  722.     akt_t = 0
  723.     cdnr = ""
  724.  
  725.     /* titel einlesen bis total oder eof erreicht */
  726.     DO WHILE ( (cdnr ~== "TOT:") & ~eof(datei_in) )
  727.  
  728.       /* 2.+...Zeile -> einlesen und auswerten)  */
  729.       zeile = READLN(datei_in)
  730.  
  731.       /* laufvariable fuer stamm */
  732.       akt_t = akt_t +1
  733.  
  734.       cd.akt_t.nr = akt_t
  735.       cd.akt_t.cdn = "Titel"akt_t
  736.  
  737.       /* in teilstrings zerlegen, unwichtiges mit dummy wegwerfen */
  738.       PARSE VALUE zeile WITH cdnr cd.akt_t.start dummy cd.akt_t.ende dummy cd.akt_t.laenge cd.akt_t.zeit dummy
  739.  
  740.       cd.akt_t.laenge = cd.akt_t.laenge - skip_lo /* Leadout kürzen */
  741.  
  742.       cd.akt_t.zeit = SUBSTR(cd.akt_t.zeit, 2, 8)
  743.  
  744.       IF debug == 1
  745.         THEN say cd.akt_t.nr": " cdnr cd.akt_t.start cd.akt_t.ende cd.akt_t.laenge cd.akt_t.zeit dummy
  746.  
  747.     END /* do while */
  748.  
  749.     CLOSE(datei_in)
  750.  
  751.     ADDRESS COMMAND "Delete >NIL: "'"'cdlist'"'  /* liste wird nicht mehr gebraucht */
  752.  
  753.   END /* if exists */
  754.  
  755.   anz_titel = akt_t -1
  756.  
  757.   SELECT
  758.  
  759.     WHEN anz_titel < 1 THEN DO
  760.       SAY
  761.       SAY "> Hmmm, keine CD im Laufwerk oder Device/Unit falsch oder belegt!"
  762.     END
  763.  
  764.     WHEN anz_titel == 1 THEN DO  /* ich geh' mal davon aus das es keine Audio-Cds mit einem Titel gibt */
  765.       SAY
  766.       SAY "> Hmmm, scheint sich um eine Daten-CD zu handeln"
  767.       anz_titel = -1
  768.     END
  769.  
  770.     WHEN anz_titel > 1 THEN DO
  771.       cdid = create_id()
  772.       IF cdid_mode == 1 THEN
  773.         CALL read_cdid()
  774.     END
  775.   END /* select */
  776.  
  777. RETURN
  778.  
  779. /* ---------------------------- */
  780.  
  781.  
  782. /****
  783.  
  784.   get_cdname  - liest vorhandene cdid daten ein und wertet sie aus
  785.  
  786.   globalen Variablen: anz_titel, cdid_dir, cdid, max_nam_len und cd.
  787.   lokale variablen  : datei_in, akt_t, zeile, sa,
  788.  
  789. ****/
  790.  
  791. read_cdid:
  792.  
  793.   IF EXISTS(cdid_dir||cdid) THEN DO
  794.  
  795.     OPEN(datei_in,cdid_dir||cdid,R)
  796.  
  797.     akt_t = 0
  798.  
  799.     /* cd.0. enthält die globalen CD Daten */
  800.     cd.0.ip   = READLN(datei_in)  /* 1.Zeile -> Interpret der CD */
  801.     cd.0.name = READLN(datei_in)  /* 2.Zeile -> CD-Name          */
  802.  
  803.     /* titel einlesen bis eof erreicht */
  804.     DO WHILE (~eof(datei_in))
  805.  
  806.       akt_t = akt_t +1
  807.  
  808.       zeile = STRIP(READLN(datei_in)) /* zeile einlesen und führende und nachgestellte Leerzeichen entfernen */
  809.  
  810.       sa = POS('B7'x,zeile)           /* nach · suchen - trennt interpret und titel bei Samplern  */
  811.  
  812.       IF sa > 0 THEN DO
  813.  
  814.          cd.akt_t.ip   = STRIP(LEFT(zeile,sa-1))    /* links davon ist der Interpret */
  815.  
  816.          cd.akt_t.name = STRIP(SUBSTR(zeile,sa+1))  /* rechts der Titel */
  817.  
  818.       END
  819.       ELSE DO                        /* kein Sampler, Interpret ist für alle Titel derselbe */
  820.  
  821.          cd.akt_t.ip = cd.0.ip
  822.          cd.akt_t.name = zeile
  823.  
  824.       END
  825.  
  826.       cd.akt_t.cdn = create_name(cd.akt_t.name, max_name_len) /* entspr. Dateinamen generieren */
  827.  
  828.       IF debug == 1
  829.         THEN say cd.akt_t.nr": " zeile  sa  cd.akt_t.ip  cd.akt_t.name  cd.akt_t.cdn
  830.  
  831.     END /* do while */
  832.  
  833.     CLOSE(datei_in)
  834.  
  835.   END
  836.  
  837.   ELSE
  838.     cdid_mode = 0
  839.  
  840. RETURN
  841.  
  842. /* ---------------------------- */
  843.  
  844.  
  845.  
  846. /****
  847.  
  848.   create_name  - erzeugt aus einem übergebenen String und der max. Länge einen korrekten
  849.                  Dos-namen.
  850.  
  851.   globalen Variablen: dirty_char, repl_spc.
  852.   lokale variablen  : s_name, s_len
  853.  
  854. ****/
  855.  
  856. create_name:
  857.  
  858.   PARSE ARG s_name, s_len
  859.  
  860.   IF LENGTH(s_name) > s_len THEN               /* Dateinamenlänge prüfen und korrigieren */
  861.     s_name = LEFT(s_name,s_len)
  862.  
  863.   s_name = TRANSLATE(s_name,'',dirty_char,'_') /* Zeichen die mit Dos kollidieren durch Unterstrich ersetzen */
  864.  
  865.   IF (repl_spc == 1) THEN
  866.     s_name = TRANSLATE(s_name,'_',' ')    /* eingegebene Leerzeichen durch Unterstrich ersetzten falls erwünscht */
  867.  
  868. RETURN s_name
  869.  
  870. /* ---------------------------- */
  871.  
  872.  
  873.  
  874. /** CTRL-C Behandlung **/
  875.  
  876. break_c:
  877.  
  878.   SAY ">>> Bearbeitung abgebrochen"
  879.  
  880.   SIGNAL ende
  881.  
  882. /* ---------------------------- */
  883.  
  884.